// -----------------------------
// Author: 		Dhaenens Gert 
// Creation: 	12/12/2014 4:20:42 PM				
// -----------------------------

#ifndef _RefPtr_inl
#define _RefPtr_inl

template<typename T>
RefPtr<T>::RefPtr(T* lpObj, Bool bIsInterface)
	: m_lpRefCount(new UInt32(1))
	, m_lpObject(lpObj)
	, m_bIsInterface(bIsInterface)
{
}
template<typename T>
RefPtr<T>::RefPtr(const RefPtr<T>& refRefPTr)
	: m_lpRefCount(refRefPTr.m_lpRefCount)
	, m_lpObject(refRefPTr.m_lpObject)
	, m_bIsInterface(refRefPTr.m_bIsInterface)
{
	AddRef();
}
template<typename T>
RefPtr<T>::~RefPtr()
{
	--(*m_lpRefCount);
	if ((*m_lpRefCount) < 1)
	{
		if (m_bIsInterface)
			m_lpObject->Release();
		else
			delete m_lpObject;
		delete m_lpRefCount;
	}
}
template<typename T>
RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& refRefPtr)
{
	if (m_lpRefCount)
	{
		--(*m_lpRefCount);
		if ((*m_lpRefCount) < 1)
		{
			if (m_bIsInterface)
				m_lpObject->Release();
			else
				delete m_lpObject;
			delete m_lpRefCount;
		}
	}

	m_lpRefCount = refRefPtr.m_lpRefCount;
	m_lpObject = refRefPtr.m_lpObject;
	m_bIsInterface = refRefPtr.m_bIsInterface;
	
	AddRef();

	return (*this);
}

template<typename T>
const T* RefPtr<T>::operator->() const
{
	return m_lpObject;
}
template<typename T>
T* RefPtr<T>::operator->()
{
	return m_lpObject;
}

template<typename T>
const T&RefPtr<T>::operator*() const
{
	return (*m_lpObject);
}
template<typename T>
T& RefPtr<T>::operator*()
{
	return (*m_lpObject);
}

template<typename T>
const T* RefPtr<T>::Get() const
{
	return m_lpObject;
}
template<typename T>
T* RefPtr<T>::Get()
{
	return m_lpObject;
}

template<typename T>
Bool RefPtr<T>::IsValid() const
{
	return (m_lpObject) && (m_lpRefCount) && ((*m_lpRefCount) > 0);
}
template<typename T>
RefPtr<T>::operator Bool()
{
	return IsValid();
}

template<typename T>
void RefPtr<T>::AddRef()
{
	++(*m_lpRefCount);
}

#endif